package com.tedu.api.io;

import org.junit.Test;

import java.io.*;


/**
 * 标准IO流---目的：  数据传输   输出文本，图片
 * Java定义---一套标准流--->数据传输---->创建流：直接创建某个流对象
 * 标准流规则：①方向划分---输入流和输出流
 *                    输入流：读入--->文件---->相对于程序--->文件往程序走
 *                    InputStream(抽象类，定义所有读的写法)【学习：子实现类】
 *                    输出流：写出--->文件---->相对于程序--->程序写出
 *                    OutputStream(抽象类：定义所有写的方法)【学习：子实现类】
 *            ②功能划分---低级流和高级流
 *                       低级流【节点流】：是建立在程序与数据之间的”普通“
 *                                    功能：负责搬运的数据流，输入流与输出流都有自己的低级流
 *                                    特点：一个字节一个字节读或者写的方法
 *                        FileOutputStream   低级流继承InputStream---文件输出流：写
 *                        FileInputStream    低级流继承OutputStream---文件输入流：读
 *                       高级流【处理流】：不能独立存在，不能直接创建对象
 *                                  功能：专门处理低级流以及其他高级流的流
 *                                  特点：搬运数据时，实现具体功能，效率提高流
 * ----总结：输出流和输入流，具备功能：低级流与高级流，
 * 实际使用：明确使用具体流
 *
 */
public class IOAPI {
    /**                                            文件输入流  ：FileInputStream
     *            输入流                   低级流---
     *                                             文件输出流：FileOutputStream
     * 标准流：         方向          功能
     *           输出流                    高级流
     *  需求：写出一个文件 fos.txt
     *  FileOutputStream构造器使用
     *  new FileOutStream(”路径+文件全称“)
     *  new FileOutputStream("路径+文件全称",boolean append)
     *  写出文件的同时实现追加效果：在第二个参数：true   追加
     *                                   false   默认不追加
     *new FileOutputStream(File file,boolean,append)
     * 写出文件，采用File传入路径加全称
     */
    @Test
    public void testFOS() throws IOException {
//        RandomAccessFile raf=
//                new RandomAccessFile("fos.txt","rw");
//
    //低级流：---文件输出流对象---从程序中写出“文件”：数据“
        FileOutputStream fos=new FileOutputStream("fos.txt",true);
        //需求：fos.txt   加一行文本
        String say="独noe无two"+":"+"叶珂";
        //字符串由字符数组组成---数组的构成---getBytes()转换为字节数组
        //输出流：----写功能：write(byte[] b)    写出字节数组
        fos.write(say.getBytes());
         //（必须操作）关闭流：---目的：节省内存开销
        fos.close();
}
/**
 * 文件输入流：读入操作
 * FileInputStream   文件输入流
 * read()  返回一个读取一个字节---效率低
 * read(字节数组byte[] b)
 * 返回一个”指定数组:空间大小“的读取---效率高
 * 需求：读入fos.txt的文件内容
 */
@Test
    public void testFIS() throws IOException {
    //创建文件输入流---读入：fos.txt
    FileInputStream fis=new FileInputStream("fos.txt");
    //读入效率高：创建字节数组-指定空间为：10KB
    byte[] data=new byte[1024*10];
    //读入操作：read(字节数组)  |以10KB读入数组
    int len=fis.read(data);
    //写出：文本---字符串--针对流操作
                       // 文件按照”指定字节数组空间“写入程序中
    //                     从0开始写入程序，写入到-1结束
    //                      len:十进制转换为二进制，写入，不等于-1，一直写入
    //一次性将给定的数据按照字节数组指定空间大小，写出成字符串
    String str=new String(data,0,len);
    System.out.println("打印Fos.txt文件："+str);
}
    /**
     * 需求：利用标准流实现视频复制粘贴
     */
    @Test
    public void testCV() throws IOException {
        //1.从“复制文件.mp4”  复制 操作---读入
         FileOutputStream fos=new FileOutputStream("新文件.mp4");
        //2.创建新文件“新文件.mp4" 粘贴 操作---写出
        FileInputStream fis=new FileInputStream("dyx.mp4");
        //3.保存每次读取的数据【字节量--int】
        int len=-1;
        byte[] data=new byte[1024*100];
        //4.一直 从“复制文件mp4”  进行读入操作，不等于-1  一直读
        while((len=fis.read(data))!=-1){
          fos.write(data,0,len);
        }
        //4.1同时 写出“新文件.mp4”
         fos.write(len);
        //5.关闭流     ---测：效率低--正常播放
        fis.close();
        fos.close();
    }
    /**
     * 需求：利用标准实现视频复制粘贴---效率低
     *                             效率高——-->空间执行：自定：100KB
     * 【高级流】BufferedInputStream     缓冲输入流---提升效率---缓冲区：字节数组【长度按照文件大小合理分配】
     *         BufferedOutputStream    缓冲输出流---提升效率---缓冲区：字节数组【长度按照文件大小合理分配】
     *  高级流使用方式：①处理低级流，套在低级流上
     *                写法：new  高级流（传入低级流引用）
     *               ②直接使用高级流的方法
     *               ③高级流不能直接创建【不能独立存在】
     */
    @Test
    public void testCVS() throws IOException {
        //创建低级流：读入”视频“
        FileInputStream fis=new FileInputStream("dyx.mp4");
        //创建高级流：套在低级流上[自带缓冲区：字节数组]
        BufferedInputStream bis=new BufferedInputStream(fis);

        //2.创建低级流：写出”高效视频.mp4“
        FileOutputStream fos=new FileOutputStream("高效视频.mp4");
        //2.创建高级流：套在低级流上【自带缓冲区：字节数组】
        BufferedOutputStream bos=new BufferedOutputStream(fos);
        //3.保存数据
        int len=-1;
        //4.高级流--低级流方法一致---read()读取内嵌缓冲区【字节数组】
        //高级流---低级流方法一致---write()写出内嵌缓冲区【字节数组】
        //一直从”dyx.mp4“读取数据，不等于-1，一直读
        //(len=bis.read())!=-1;
        while((len=bis.read())!=-1){
            bos.write(len);
        }
    }
}